package com.ruoyi.service.impl;

import java.math.BigDecimal;
import java.util.*;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.domain.Book;
import com.ruoyi.domain.Penalty;
import com.ruoyi.domain.ShelvedBook;
import com.ruoyi.domain.dto.HotListDto;
import com.ruoyi.domain.dto.LendMessageDto;
import com.ruoyi.domain.dto.UncompensatedPenaltyDto;
import com.ruoyi.domain.dto.UserLendDto;
import com.ruoyi.mapper.BookMapper;
import com.ruoyi.mapper.PenaltyMapper;
import com.ruoyi.mapper.ShelvedBookMapper;
import com.ruoyi.service.ILendMessageService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.mapper.SysDictDataMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.mapper.LendMessageMapper;
import com.ruoyi.domain.LendMessage;

/**
 * 图书借阅Service业务层处理
 *
 * @author qyb
 * @date 2023-12-26
 */
@Service
public class LendMessageServiceImpl implements ILendMessageService
{
    @Autowired
    private LendMessageMapper lendMessageMapper;
    @Autowired
    private BookMapper bookMapper;
    @Autowired
    private PenaltyMapper penaltyMapper;
    @Autowired
    private ShelvedBookMapper shelvedBookMapper;
    @Autowired
    private SysDictDataMapper sysDictDataMapper;

    /**
     * 查询图书借阅
     *
     * @param lendId 图书借阅主键
     * @return 图书借阅
     */
    @Override
    public LendMessage selectLendMessageByLendId(Long lendId)
    {
        return lendMessageMapper.selectLendMessageByLendId(lendId);
    }

    /**
     * 查询图书借阅列表
     *
     * @param lendMessage 图书借阅
     * @return 图书借阅
     */
    @Override
    public List<LendMessage> selectLendMessageList(LendMessage lendMessage)
    {
        return lendMessageMapper.selectLendMessageList(lendMessage);
    }

    /**
     * 多功能查询图书借阅列表
     *
     * @param lendMessageDto 图书借阅
     * @return 图书借阅
     */
    @Override
    public List<LendMessageDto> getLendMessage(LendMessageDto lendMessageDto) {
        return lendMessageMapper.selectLendMessage(lendMessageDto);
    }

    /**
     * 查询图书热榜
     *
     * @param lendMessageDto 图书借阅
     * @return 图书借阅
     */
    @Override
    public List<HotListDto> getHotList(LendMessageDto lendMessageDto) {
        return lendMessageMapper.selectHotList(lendMessageDto);
    }
    /**
     * 查询快到期图书
     *
     * @param lendMessageDto 图书借阅
     * @return 图书借阅
     */
    @Override
    public List<LendMessageDto> getExpiring(LendMessageDto lendMessageDto) {
        List<LendMessageDto> expiringBooks = new ArrayList<>();

        // 获取当前日期
        Date currentDate = new Date();

        // 假设LendMessage包含了截止日期的信息，这里使用一个类似的字段名假设为dueDate
        List<LendMessageDto> allLendMessages = lendMessageMapper.selectLendMessage(lendMessageDto);

        // 遍历所有借阅信息，找出即将到期的图书
        for (LendMessageDto lmd : allLendMessages) {
            Date shouldBackTime = lmd.getShouldBackTime(); // 获取图书归还截止日期
            long diffInMillies = shouldBackTime.getTime() - currentDate.getTime();//截止日期与当前日期之间的时间差，以毫秒为单位
            long diffInDays = diffInMillies / (1000 * 60 * 60 * 24);//这个表达式是用来将毫秒转换为天数的计算
            List<SysDictData> list = sysDictDataMapper.selectDictDataByType("sys_lend_expiring");
            SysDictData sysDictData = list.get(0);
            int expiringDay = Integer.parseInt(sysDictData.getDictValue());
            boolean flag = (diffInDays < expiringDay);
            // 如果截止日期在当前日期之后，但在某个预定义的阈值日期之内
            if (shouldBackTime.after(currentDate) && flag && lmd.getIsBack()==0) {
                expiringBooks.add(lmd); // 将即将到期的图书添加到结果列表中
            }
        }
        return expiringBooks;
    }

    /**
     * 借阅图书
     *
     * @param lendMessage 图书借阅
     * @return 结果
     */
    @Override
    public AjaxResult lendBook(LendMessage lendMessage) {
        Date currentDate = new Date();//获取当前时间
        Long userId = SecurityUtils.getUserId();
        UncompensatedPenaltyDto uncompensatedPenaltyDto = penaltyMapper.selectUncompensatedPenaltyByUserId(userId);
        if(uncompensatedPenaltyDto.getCount()>0){
            return AjaxResult.error("有未赔偿罚款记录,借阅失败");
        }

        UserLendDto userLendDto = lendMessageMapper.selectLendMessageByUserId(userId);
        List<SysDictData> list = sysDictDataMapper.selectDictDataByType("sys_lend_count");//获取借阅上限
        SysDictData sysDictData = list.get(0);
        int lendCount = Integer.parseInt(sysDictData.getDictValue());
        if(userLendDto.getCount()==lendCount){
            return AjaxResult.error("在借数量达到"+lendCount+"上限,借阅失败");
        }
        List<SysDictData> list1 = sysDictDataMapper.selectDictDataByType("sys_lend_should");//获取借阅期限
        SysDictData sysDictData1 = list1.get(0);
        int amount = Integer.parseInt(sysDictData1.getDictValue());
        Calendar calendar = Calendar.getInstance();//计算应还日期，amount：30为30天后
        calendar.setTime(currentDate);
        calendar.add(Calendar.DATE, amount);
        Date shouldBackTime = calendar.getTime();

        lendMessage.setLendDate(currentDate);
        lendMessage.setCreateTime(currentDate);
        lendMessage.setUserId(userId);
        lendMessage.setShouldBackTime(shouldBackTime);

//        Book book =new Book();
//        book.setBookId(lendMessage.getBookId());
//        book = bookMapper.selectBookByBookId(book.getBookId());
//        Long num = book.getNumber();
        ShelvedBook shelvedBook = shelvedBookMapper.selectShelvedBookByBookId(lendMessage.getBookId());
        if(shelvedBook == null){
            return AjaxResult.error("该图书未上架");//表示借阅失败
        }
        int num = shelvedBook.getShelvedNumber();

        if(num>0){
            num-=1;
            shelvedBook.setShelvedNumber(num);
        }else {
            return AjaxResult.error("图书数量不足，借阅失败");//数量不足，借阅失败
        }
        if(lendMessageMapper.insertLendMessage(lendMessage) >0 && shelvedBookMapper.updateShelvedBook(shelvedBook)==1){
            return AjaxResult.success("借阅成功");//借阅成功
        }else {
            return AjaxResult.error("借阅失败");//表示借阅失败
        }
    }

    /**
     * 归还图书
     *
     * @param lendMessage 图书借阅
     * @return 结果
     */
    @Override
    public AjaxResult returnBook(LendMessage lendMessage) {
        Date currentDate = new Date();//获取当前时间
        Long lendId = lendMessage.getLendId();
        if(lendMessageMapper.selectLendMessageByLendId(lendId)==null)
            return AjaxResult.error("没有该条借阅记录，归还失败");
        LendMessage lm = lendMessageMapper.selectLendMessageByLendId(lendId);

//        Book book = bookMapper.selectBookByBookId(lm.getBookId());
//        Long num = book.getNumber();
        ShelvedBook shelvedBook = shelvedBookMapper.selectShelvedBookByBookId(lm.getBookId());
        int num = shelvedBook.getShelvedNumber();
        num+=1;
        shelvedBook.setShelvedNumber((num));
        lendMessage.setBackDate(currentDate);
        lendMessage.setIsBack(1);
        lendMessage.setLendId(lendId);
        if (lm.getIsBack()==1){
            return AjaxResult.error("还书失败，已经归还");
        }
        if(lendMessageMapper.updateLendMessage(lendMessage) >0 && shelvedBookMapper.updateShelvedBook(shelvedBook)==1){
            return AjaxResult.success("还书成功");
        }else {
            return AjaxResult.error("还书失败");
        }
    }

    /**
     * 逻辑删除借阅列表
     *
     * @param lendIds 图书借阅
     * @return 结果
     */
    @Override
    public AjaxResult updateIsDelete(String lendIds)
    {
        int count=0;
        JSONObject jsonObject = JSONObject.parseObject(lendIds);
        String str = jsonObject.get("lendIds").toString();
        String[] stringArray = str.split(","); // 使用逗号分隔字符串并生成字符串数组

        Long[] longArray = new Long[stringArray.length];
        for (int i = 0; i < stringArray.length; i++) {
            try {
                longArray[i] = Long.parseLong(stringArray[i].trim()); // 将每个字符串转换为 Long 类型
            } catch (NumberFormatException e) {
                // 处理无法转换为 Long 类型的情况
                e.printStackTrace();
                // 可以选择跳过该值、设置默认值，或者抛出异常等
            }
        }
        for (Long la :longArray){
            LendMessage lm = new LendMessage();
            lm.setLendId(la);
            if(lendMessageMapper.updateIsDelete(lm)>0){
                count++;
            }
        }
        if (count == stringArray.length){
            return AjaxResult.success("删除成功");
        }else {
            return AjaxResult.error("删除失败");
        }

    }

    /**
     * 提交丢失申请
     *
     * @param lendMessage 图书借阅
     * @return 结果
     */
    @Override
    public AjaxResult lossReport(LendMessage lendMessage) {
        Long lendId = lendMessage.getLendId();
        Date currentDate = new Date();//获取当前时间
        LendMessage lm = lendMessageMapper.selectLendMessageByLendId(lendId);
        if(lm.getState()==1){
            return AjaxResult.error("提交失败,已经提交过了");
        }
        Long bookId = lm.getBookId();
        Book book = bookMapper.selectBookByBookId(bookId);
        Long userId = lm.getUserId();
        Penalty penalty = new Penalty();
        penalty.setBookId(bookId);
        penalty.setUserId(userId);
        penalty.setUpdateTime(currentDate);
        penalty.setCreateTime(currentDate);
        penalty.setLendId(lendId);
        List<SysDictData> list = sysDictDataMapper.selectDictDataByType("sys_penalty_rate");//获取赔偿比例
        SysDictData sysDictData = list.get(0);
        BigDecimal rate = new BigDecimal(sysDictData.getDictValue());
        BigDecimal price = book.getPrice().multiply(rate);
        penalty.setPenaltyPrice(price);
        Calendar calendar = Calendar.getInstance();//计算应还日期，amount：30为30天后
        calendar.setTime(currentDate);
        List<SysDictData> list1 = sysDictDataMapper.selectDictDataByType("sys_pay_day");//获取应赔天数
        SysDictData sysDictData1 = list1.get(0);
        int amount = Integer.parseInt(sysDictData1.getDictValue());
        calendar.add(Calendar.DATE, amount);
        Date shouldTime = calendar.getTime();
        penalty.setShouldTime(shouldTime);
        penalty.setRemark("丢失");
//        penalty.setCreateBy(Long.toString(userId));
        lendMessage.setState(1);
        if(lendMessageMapper.updateLendMessage(lendMessage) >0 &&penaltyMapper.insertPenalty(penalty) ==1){
            return AjaxResult.success("提交成功");
        }else {
            return AjaxResult.error("提交失败");
        }
    }

    /**
     * 续借图书
     *
     * @param lendMessage 图书借阅
     * @return 结果
     */
    @Override
    public AjaxResult renewBook(LendMessage lendMessage) {
        Long lendId = lendMessage.getLendId();
        LendMessage lm = lendMessageMapper.selectLendMessageByLendId(lendId);
        Date lendDate = lm.getLendDate();
        Date shouldBackTime = lm.getShouldBackTime();
        if(lm.getIsBack()==1)
            return AjaxResult.error("该书已归还，续借失败");
        Integer renewCount = lm.getRenewCount();
        long diffInMillies = shouldBackTime.getTime() - lendDate.getTime();//截止日期与当前日期之间的时间差，以毫秒为单位
        long diffInDays = diffInMillies / (1000 * 60 * 60 * 24);//这个表达式是用来将毫秒转换为天数的计算
        List<SysDictData> list = sysDictDataMapper.selectDictDataByType("sys_renew_limit_day");//获取续借天数限制
        SysDictData sysDictData = list.get(0);
        int renewLimitDay = Integer.parseInt(sysDictData.getDictValue());
        boolean flag = (diffInDays >= renewLimitDay);
        // 如果截止日期在当前日期之后，但在某个预定义的阈值日期之外（比如20天外）
        if(flag)
            return AjaxResult.error("距离应还日期还有"+renewLimitDay+"天以上，续借失败");
        List<SysDictData> list1 = sysDictDataMapper.selectDictDataByType("sys_renew_limit_count");//获取续借次数
        SysDictData sysDictData1 = list1.get(0);
        int renewLimitCount = Integer.parseInt(sysDictData1.getDictValue());
        if (shouldBackTime.after(lendDate) && renewCount<renewLimitCount) {
            // 给日期加上30天
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(shouldBackTime);
            List<SysDictData> list2 = sysDictDataMapper.selectDictDataByType("sys_renew_day");//获取续借天数
            SysDictData sysDictData2 = list2.get(0);
            int renewDay = Integer.parseInt(sysDictData2.getDictValue());
            calendar.add(Calendar.DAY_OF_MONTH, renewDay);
            Date newShoudBackTime = calendar.getTime();
            renewCount++;
            lendMessage.setRenewCount(renewCount);
            lendMessage.setShouldBackTime(newShoudBackTime);
            if(lendMessageMapper.updateLendMessage(lendMessage)>0) {
                return AjaxResult.success("续借成功");
            }else{
                return AjaxResult.error("续借失败");
            }
        }else {
            return AjaxResult.error("已到达续借次数上限，续借失败");
        }
    }

    /**
     * 新增图书借阅
     *
     * @param lendMessage 图书借阅
     * @return 结果
     */
    @Override
    public AjaxResult insertLendMessage(LendMessage lendMessage)
    {
        Date currentDate = new Date();
        Long userId = lendMessage.getUserId();
        int isBack = 0;
        if(lendMessage.getIsBack()!= null){
            isBack = lendMessage.getIsBack();
        }

        UserLendDto userLendDto = lendMessageMapper.selectLendMessageByUserId(userId);
        List<SysDictData> list = sysDictDataMapper.selectDictDataByType("sys_lend_count");//获取借阅上限
        SysDictData sysDictData = list.get(0);
        int lendCount = Integer.parseInt(sysDictData.getDictValue());
        if(userLendDto.getCount()>=lendCount && isBack==0){
            return AjaxResult.error("在借数量达到"+lendCount+"本上限,借阅失败");
        }

        lendMessage.setLendDate(lendMessage.getLendDate());
        lendMessage.setCreateTime(currentDate);
        lendMessage.setUserId(userId);
        lendMessage.setShouldBackTime(lendMessage.getShouldBackTime());

        Book book =new Book();
        book.setBookId(lendMessage.getBookId());
        book = bookMapper.selectBookByBookId(book.getBookId());
        Long num = book.getNumber();

        if (isBack==0){
            if(book.getNumber()>0){
                num-=1;
                book.setNumber((num));
                if (lendMessage.getShouldBackTime() == null){
                    List<SysDictData> list1 = sysDictDataMapper.selectDictDataByType("sys_lend_should");//获取借阅期限
                    SysDictData sysDictData1 = list1.get(0);
                    int amount = Integer.parseInt(sysDictData1.getDictValue());
                    Calendar calendar = Calendar.getInstance();//计算应还日期，amount：30为30天后
                    calendar.setTime(currentDate);
                    calendar.add(Calendar.DATE, amount);
                    Date shouldBackTime = calendar.getTime();
                    lendMessage.setShouldBackTime(shouldBackTime);
                }
            }else {
                return AjaxResult.error("图书数量不足，借阅失败");//数量不足，借阅失败
            }
        }else {
            if (lendMessage.getBackDate() == null){
                return AjaxResult.error("未填写归还日期，新增失败");
            }
        }
        if(lendMessageMapper.insertLendMessage(lendMessage) >0 && bookMapper.updateBook(book)==1){
            return AjaxResult.success("操作成功");//借阅成功
        }else {
            return AjaxResult.error("操作失败");//表示借阅失败
        }
    }

    /**
     * 修改图书借阅
     *
     * @param lendMessage 图书借阅
     * @return 结果
     */
    @Override
    public AjaxResult updateLendMessage(LendMessage lendMessage)
    {
        if (lendMessage.getLendId() == null){
            return AjaxResult.error("缺少lendId，修改失败");
        }
        long lendId = lendMessage.getLendId();
        LendMessage lm = lendMessageMapper.selectLendMessageByLendId(lendId);
        int isBack = lm.getIsBack();;
        if(lendMessage.getIsBack() != null){
            isBack = lendMessage.getIsBack();
        }

        int state = lm.getState();
        if(lendMessage.getState() != null){
            state = lendMessage.getState();
        }

        int isBack2 = lm.getIsBack();
        int state2 = lm.getState();
        long bookId = lm.getBookId();
        long userId = lm.getUserId();
        Date currentDate = new Date();//获取当前时间

        if(state==0 && state2==1){
            Penalty penalty = penaltyMapper.selectPenaltyByLendId(lendId);
            penalty.setIsIndemnify(1);
            penalty.setUpdateTime(currentDate);
            if (penaltyMapper.updatePenalty(penalty)!=1){
                return AjaxResult.error("修改失败");
            }
        }


        if(state==1 && state2==0){
            Book book = bookMapper.selectBookByBookId(bookId);
            Penalty penalty = new Penalty();
            penalty.setBookId(bookId);
            penalty.setUserId(userId);
            penalty.setUpdateTime(currentDate);
            penalty.setCreateTime(currentDate);
            penalty.setLendId(lendId);
            List<SysDictData> list = sysDictDataMapper.selectDictDataByType("sys_penalty_rate");//获取赔偿比例
            SysDictData sysDictData = list.get(0);
            BigDecimal rate = new BigDecimal(sysDictData.getDictValue());
            BigDecimal price = book.getPrice().multiply(rate);
            penalty.setPenaltyPrice(price);
            Calendar calendar = Calendar.getInstance();//计算应还日期，amount：30为30天后
            calendar.setTime(currentDate);
            List<SysDictData> list1 = sysDictDataMapper.selectDictDataByType("sys_pay_day");//获取应赔天数
            SysDictData sysDictData1 = list1.get(0);
            int amount = Integer.parseInt(sysDictData1.getDictValue());
            calendar.add(Calendar.DATE, amount);
            Date shouldTime = calendar.getTime();
            penalty.setShouldTime(shouldTime);
            if(penaltyMapper.insertPenalty(penalty) !=1){
                return AjaxResult.error("罚款失败");
            }
        }
        if(isBack==1 && isBack2==0){
            Book book = bookMapper.selectBookByBookId(bookId);
            Long num = book.getNumber();
            num+=1;
            book.setNumber((num));
            if(lendMessageMapper.updateLendMessage(lendMessage) <=0 || bookMapper.updateBook(book)!=1){
                return AjaxResult.error("还书失败");
            }
        }
        if(isBack==0 && isBack2==1){
            Book book = bookMapper.selectBookByBookId(bookId);
            Long num = book.getNumber();
            num-=1;
            book.setNumber((num));
            if(lendMessageMapper.updateLendMessage(lendMessage) <=0 || bookMapper.updateBook(book)!=1){
                return AjaxResult.error("修改失败");
            }
        }
        if(lendMessageMapper.updateLendMessage(lendMessage) >0){
            return AjaxResult.success("修改成功");
        }else {
            return AjaxResult.error("修改失败");
        }
    }

    /**
     * 批量删除图书借阅
     *
     * @param lendIds 需要删除的图书借阅主键
     * @return 结果
     */
    @Override
    public int deleteLendMessageByLendIds(Long[] lendIds)
    {
        return lendMessageMapper.deleteLendMessageByLendIds(lendIds);
    }

    /**
     * 删除图书借阅信息
     *
     * @param lendId 图书借阅主键
     * @return 结果
     */
    @Override
    public int deleteLendMessageByLendId(Long lendId)
    {
        return lendMessageMapper.deleteLendMessageByLendId(lendId);
    }



}
